function Ucs2CodeToUtf8Code(code) {
    let ret = [];
    if (code < 0x0080) {
        ret.push(code&0x7F);
    }
    else if (code < 0x0800) {
        ret.push(0xC0 | ((code >> 6) & 0x1F));
        ret.push(0x80 | ((code >> 0) & 0x3F));
    }
    else if (code < 0x10000) {
        ret.push(0xE0 | ((code >> 12) & 0x0F));
        ret.push(0x80 | ((code >>  6) & 0x3F));
        ret.push(0x80 | ((code >>  0) & 0x3F));
    }
    else
    {
        ret.push(((code>>18)&0x07)|0xF0);
        ret.push(((code>>12)&0x3F)|0x80);
        ret.push(((code>>6)&0x3F)|0x80);
        ret.push((code&0x3F)|0x80);
    }
    return ret;
}

function Ucs2ToUtf8(str) {
    let utf = "";
    for (let i = 0; i < str.length; i++)
    {
        let code = Ucs2CodeToUtf8Code(str.charCodeAt(i));//返回每个字符的Unicode 编码
        for (let j = 0; j < code.length; j++) {
            utf += String.fromCharCode(code[j]);
        }
    }
    return utf;
}

function Utf8ArrayToUcs2(arr) {
    let str = "";
    let tmp;

    for(let i = 0; i < arr.length; i++)
    {
        // 英文字符集合
        if(arr[i] >> 7 == 0x00)
        {
            str += String.fromCharCode(arr[i]);
            continue;
        }
        // 其他字符集
        else if(arr[i] >> 5 == 0x06)
        {
            tmp = ((arr[i + 0] & 0x1f) << 6) |
                  ((arr[i + 1] & 0x3f) << 0);
            str += String.fromCharCode(tmp);
            i++;
            continue;
        }
        // 中文字符集
        else if(arr[i] >> 4 == 0x0e)
        {
            tmp = ((arr[i + 0] & 0x0f) << 12) |
                  ((arr[i + 1] & 0x3f) <<  6) |
                  ((arr[i + 2] & 0x3f) <<  0);
            str += String.fromCharCode(tmp);
            i += 2;
            continue;
        }
        // 其他字符集
        else if(arr[i] >> 3 == 0x1f)
        {
            tmp = ((arr[i + 0] & 0x07) << 18) |
                  ((arr[i + 1] & 0x3f) << 12) |
                  ((arr[i + 2] & 0x3f) <<  6);
                  ((arr[i + 3] & 0x3f) <<  0);
            str += String.fromCharCode(tmp);
            i += 3;
            continue;
        }
        // 非法字符集
        else
        {
            throw "不是UTF-8字符集"
        }
    }

    return str;
}

function Utf8ToUcs2(utf) {
    let str = "";
    let tmp;

    for(let i = 0; i < utf.length; i++)
    {
        // 英文字符集合
        if(utf.charCodeAt(i) >> 7 == 0x00)
        {
            str += utf.charAt(i);
            continue;
        }
        // 其他字符集
        else if(utf.charCodeAt(i) >> 5 == 0x06)
        {
            tmp = ((utf.charCodeAt(i + 0) & 0x1f) << 6) |
                  ((utf.charCodeAt(i + 1) & 0x3f) << 0);
            str += String.fromCharCode(tmp);
            i++;
            continue;
        }
        // 中文字符集
        else if(utf.charCodeAt(i) >> 4 == 0x0e)
        {
            tmp = ((utf.charCodeAt(i + 0) & 0x0f) << 12) |
                  ((utf.charCodeAt(i + 1) & 0x3f) <<  6) |
                  ((utf.charCodeAt(i + 2) & 0x3f) <<  0);
            str += String.fromCharCode(tmp);
            i += 2;
            continue;
        }
        // 其他字符集
        else if(utf.charCodeAt(i) >> 3 == 0x1f)
        {
            tmp = ((utf.charCodeAt(i + 0) & 0x07) << 18) |
                  ((utf.charCodeAt(i + 1) & 0x3f) << 12) |
                  ((utf.charCodeAt(i + 2) & 0x3f) <<  6);
                  ((utf.charCodeAt(i + 3) & 0x3f) <<  0);
            str += String.fromCharCode(tmp);
            i += 3;
            continue;
        }
        // 非法字符集
        else
        {
            throw "不是UTF-8字符集"
        }
    }

    return str;
}

function Ucs2ToUtf8Uint8Array(str) {
    let arr = [];
    for (let i = 0; i < str.length; i++)
    {
        let code = Ucs2CodeToUtf8Code(str.charCodeAt(i));//返回每个字符的Unicode 编码
        if (code.length) {
            arr = arr.concat(code);
        }
    }
    return new Uint8Array(arr);
}

function Uint16ArrayToString(arr) {
    let ret = "";
    for (let i = 0; i < arr.length; i++) {
        ret += String.fromCharCode(arr[i]);
    }
    return ret;
}

function StringToUint16Array(str) {
    let arr = [];
    for (let i = 0, j = str.length; i < j; ++i) {
        arr.push(str.charCodeAt(i));
    }
    return new Uint16Array(arr);
}

exports.Ucs2ToUtf8 = Ucs2ToUtf8;
exports.Utf8ArrayToUcs2 = Utf8ArrayToUcs2;
exports.Utf8ToUcs2 = Utf8ToUcs2;
exports.Ucs2ToUtf8Uint8Array = Ucs2ToUtf8Uint8Array;
exports.Uint16ArrayToString = Uint16ArrayToString;
exports.StringToUint16Array = StringToUint16Array;
